#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
第一行注释是为了告诉Linux/OS X系统，这是一个Python可执行程序，Windows系统会忽略这个注释；
第二行注释是为了告诉Python解释器，按照UTF-8编码读取源代码，否则，你在源代码中写的中文输出可能会有乱码。
'''

'''面向对象高级编程学习'''

class Student(object):
    pass
	
#绑定一个属性
s=Student()
s.name='zhijie'

print s.name

#绑定一个方法

def set_age(self,age):
    self.age=age

from types import MethodType

s.set_age=MethodType(set_age,s,Student)
s.set_age(25)
print s.age

#但是，给一个实例绑定的方法，对另一个实例是不起作用的

#为了给所有实例都绑定方法，可以给class绑定方法

def set_score(self,score):
	self.score=score

Student.set_score=MethodType(set_score,None,Student)

s1=Student()
s1.set_score(100)
print s1.score

#Python允许在定义class的时候，定义一个特殊的__slots__变量，来限制该class能添加的属性：

class People(object):
    __slots__=('name','age')
    pass
	
p=People()
p.name='tang'
p.age=1
# p.score=2

#__slots__定义的属性仅对当前类起作用，对继承的子类是不起作用


#使用@property

class Student(object):
	
	#这个方法相当于getter
	@property
	def score(self):
		#这里不能使用self.score，不然会导致无线循环
		return self._score
	
	#这个方法相当于setter
	@score.setter	
	def score(self,value):
		if not isinstance(value,int):
			raise ValueError('score must be an integer!')
		if value<0 or value>100:
			raise ValueError('score must between 0~100!')
		self._score=value

s=Student()
s.score=60 #实际转化为s.set_score(60)
print s.score #实际转化为s.get_score()
# s.score=9999


class Man(object):
	
	@property
	def name(self):
		#这里不能使用self.name，不然会导致无线循环
		return self._name

	@name.setter
	def name(self,value):
		self._name=value
		
	#age只读
	@property
	def age(self):
		return self._age

man=Man()
man.name='god'
print man.name